#include <linux/init.h>
#include <linux/module.h>
#include <linux/netfilter_ipv4.h>
#include <net/ip.h>
#include "../include/pub.h"
#include "uf_ipv4.h"
#include "uf_rule.h"
#include "uf_rule_adv.h"

u64 uf_jiffies;

inline static bool UF4_ishttp(unsigned short dport)
{
    if ((htons(UF_HTTP_PORT) == dport) || 
        (htons(UF_HTTP_PORT2) == dport))
    {
        return true;
    }
    
    return false;
}

unsigned int UF4_filter(struct sk_buff *skb)
{
    unsigned int ret = NF_ACCEPT;
    struct iphdr *iph = NULL;
    struct tcphdr *tcph = NULL;
    struct udphdr *udph = NULL;
    UF4_MatchInfo_S filter;

    iph = ip_hdr(skb);
    if (NULL == iph)
    {
        return ret;
    }

    /* filter key */
    if ((IPPROTO_TCP == iph->protocol) &&
        (NULL != (tcph = tcp_hdr(skb))))
    {
        filter.sip = iph->saddr;
        filter.dip = iph->daddr;
        filter.sport = tcph->source;
        filter.dport = tcph->dest;
    }
    else if ((IPPROTO_UDP == iph->protocol) &&
             (NULL != (udph = udp_hdr(skb))))
    {
        filter.sip = iph->saddr;
        filter.dip = iph->daddr;
        filter.sport = udph->source;
        filter.dport = udph->dest;
    }
    else
    {
        return ret;
    }

    /* http */
    if ((htons(UF_HTTP_PORT) == filter.dport) ||
        (htons(UF_HTTP_PORT2) == filter.dport))
    {
        /* tcp PSH */
        if (tcph->psh)
        {        
            ret = UF_match_rule(&filter, skb);
        }
    }
    /* https */
    else if (IPPROTO_UDP == iph->protocol)
    {
        ret = UF_match_https(&filter, skb);
    }
 
    return ret;    
}
